1. Field of the Invention
The present invention generally relates to computers and computer software. More specifically, the invention is generally related to determining thread termination in a debugging environment.
2. Description of the Related Art
Locating, analyzing and correcting suspected faults in a computer program is a process known as “debugging.” Typically, a programmer uses another computer program commonly known as a “debugger” to debug a program under development.
Conventional debuggers typically support two primary operations to assist a computer programmer. A first operation supported by conventional debuggers is a “step” function, which permits a computer programmer to process instructions (also known as “statements”) in a computer program one-by-one, and see the results upon completion of each instruction. While the step operation provides a programmer with a large amount of information about a program during its execution, stepping through hundreds or thousands of program instructions can be extremely tedious and time consuming, and may require a programmer to step through many program instructions that are known to be error-free before a set of instructions to be analyzed are executed.
To address this difficulty, a second operation supported by conventional debuggers is a breakpoint operation, which permits a computer programmer to identify with a “breakpoint” a precise instruction for which it is desired to halt execution of a computer program during execution. As a result, when a computer program is executed by a debugger, the program executes in a normal fashion until a breakpoint is reached, and then stops execution and displays the results of the computer program to the programmer for analysis.
Typically, step operations and breakpoints are used together to simplify the debugging process. Specifically, a common debugging operation is to set a breakpoint at the beginning of a desired set of instructions to be analyzed, and then begin executing the program. Once the breakpoint is reached, the program is halted, and the programmer then steps through the desired set of instructions line by line using the step operation. Consequently, a programmer is able to quickly isolate and analyze a particular set of instructions without having to step through irrelevant portions of a computer program.
Most breakpoints supported by conventional debuggers are unconditional, meaning that once such a breakpoint is reached, execution of the program is always halted. Some debuggers also support the use of conditional breakpoints, which only halt execution of a program when a variable used by the program is set to a predetermined value at the time such a breakpoint is reached.
Some operating systems, such as UNIX and Windows NT, allow multiple parts, or threads, of one or more processes to run simultaneously. These operating systems are referred to as multi-threaded. This type of parallel processing allows for faster execution of such processes. However, multi-threaded operating systems complicate debugging by making use of breakpoints inefficient. Conventional multi-thread debuggers do not identify the activities and termination of the various control threads. The insight given is limited to listing thread identifiers without any relation to when a thread terminates. The user must often painfully set and hit each of a large number of breakpoints to deduce when a thread terminates. This presumes the user has taken the effort to first determine the possible thread termination points in the code being debugged. Most operating systems have an instruction that causes a thread to terminate normally. However, this termination point can occur in potentially many places within the code. The thread may also terminate abnormally because the code being debugged takes an exception, a machine check occurs, etc. Therefore, the point at which thread termination occurs is unpredictable, making it very difficult and time consuming to set breakpoints in all the possible termination points.
Therefore, a significant need exists for a manner of determining the termination of threads so that multi-threaded code can be debugged more readily.